from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings


class FastDFSStorage(Storage):
    """自定义文件存储方案：将文件转存到FDFS"""

    def __init__(self, client_conf=None, base_url=None):
        self.client_conf = client_conf or settings.FDFS_CLIENT_CONF
        self.base_url = base_url or settings.FDFS_BASE_URL

    def _open(self, name, mode='rb'):
        """
        打开文件时被调用的
        这个自定义的类是做文件的存储的，不会涉及到文件的打开，所以没有实际的用处，但是文档要求我必须实现，所以pass
        """
        pass

    def _save(self, name, content):
        """
        保存文件时被调用的
        就是要借这个方法的调用时机，将发送给django的文件存储到fastdfs
        :param name: 要保存的文件的名字
        :param content: 要保存的文件对象，File类型的对象，通过read()读取文件对象中存储的文件二进制
        :return: file_id
        """
        # 创建client对象
        # client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf')
        client = Fdfs_client(self.client_conf)

        # 调用上传的方法：upload_by_buffer('文件二进制') 利用要保存的文件的二进制上传到fdfs
        ret = client.upload_by_buffer(content.read())

        # 判断是否收藏成功
        if ret.get('Status') != 'Upload successed.':
            raise Exception('fastdfs upload error')

        # 读取出file_id
        file_id = ret.get('Remote file_id')
        # 返回file_id
        # _save()的返回值，会自动的存储到ImageField字段对应的模型类属性中，并自动的同步到数据库
        return file_id

    def exists(self, name):
        """
        如果文件已经存在,就返回True,那么该文件不再存储，save()方法不再被调用了
        :param name: 判断是否存在的文件的名字
        :return: False；告诉Django,要保存的name对应的文件不存在，就会调用save()
        """
        return False

    def url(self, name):
        """
        返回文件的相对路径
        :param name: 文件的名字: group1/M00/00/00/wKhnhFtWOgCAZwjTAAExf6lt6Ck2361686
        :return: http://192.168.103.132:8888/group1/M00/00/00/wKhnhFtWOgCAZwjTAAExf6lt6Ck2361686
        <img src="{{ content.image.url }}">
        """

        return self.base_url + name
